package tool
 
import parser.Parser
import analyzer.Analyzer
import analyzer.TypeChecker
import code.CodeGenerator
import analyzer.ExceptionChecker
 
import scala.io.Source
 
class Compiler(val fileName: String)
	extends Reporter
	with Parser
    with Analyzer
    with TypeChecker
	with ExceptionChecker
    with CodeGenerator 
    {
 
	val source: Source = Source.fromFile(fileName)
 
	def compile(classDir: String): Unit = {
		import parser.Trees._
		import analyzer.Symbols._
 
		val outputDir = classDir+"/"
 
		val checkDir: java.io.File = new java.io.File(outputDir)
    	if(!checkDir.exists) checkDir.mkdir
		if(!checkDir.isDirectory) fatalError("Cannot find output directory " + outputDir)
		// Parsing
		var parsedTree: Option[Tree] = None
		parsedTree = Some(parseSource)
		terminateIfErrors

		val mainProg: Program = parsedTree match {
			case Some(p:Program) => p
			case _ => scala.Predef.error("Main program expected from parser.")
		}

		// Name analysis
		val global: GlobalScope = analyzeSymbols(mainProg)
		terminateIfErrors
 
		// Type checking
		typeCheck(mainProg, global)
		terminateIfErrors

		exceptionCheck(mainProg)
		terminateIfErrors


		// Create classes
		mainProg.classes foreach {
			ct => generateClassFile(global, ct, outputDir)
		}
		
		generateMainObjectClassFile(mainProg.main, global, outputDir)
  	}
}
